{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python基础----函数function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "   函数是组织好的，可重复使用的，用来实现单一，或相关联功能的代码段。\n",
    "   函数能提高应用的模块性，和代码的重复利用率。前面的文章中也涉及到一些Python的内建函数，比如print()；当需要实现复杂的或个性化的操作时，就可以自己创建函数，叫做用户自定义函数。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 一、定义一个函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义一个由自己想要功能的函数，以下是简单的规则：\n",
    "   函数代码块以 def 关键词开头，后接函数标识符名称和圆括号 ()。\n",
    "   任何传入参数和自变量必须放在圆括号中间，圆括号之间可以用于定义参数。\n",
    "   函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。\n",
    "   函数内容以冒号起始，并且缩进。\n",
    "   return [表达式] 结束函数，选择性地返回一个值给调用方。不带表达式的return相当于返回 None。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 语法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def 函数名（参数列表）:\n",
    "    函数体"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def area(width,height):\n",
    "...     y=width*height\n",
    "...     return(y)\n",
    "area(3,4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 二、函数调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "调用函数!\n",
      "再次调用同一函数\n"
     ]
    }
   ],
   "source": [
    "# 定义函数\n",
    "def print_str( str ):\n",
    "# 打印任何传入的字符串\n",
    "    print (str)\n",
    "    return\n",
    " \n",
    "# 调用函数\n",
    "print_str(\"调用函数!\")\n",
    "print_str(\"再次调用同一函数\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 三、参数传递"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## python 传不可变对象实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "def ChangeInt( a ):\n",
    "    a = 10\n",
    "    return(a)\n",
    " \n",
    "b = 2\n",
    "c = ChangeInt(b)\n",
    "print( b ) # 结果是 2\n",
    "print( c ) # 结果是 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## python 传可变对象实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内取值： [10, 20, 30, [1, 2, 3, 4]]\n",
      "函数外取值:  [10, 20, 30, [1, 2, 3, 4]]\n"
     ]
    }
   ],
   "source": [
    "def changeme(mylist):\n",
    "    \"\"\"修改传入的列表\"\"\"\n",
    "    mylist.append([1,2,3,4])\n",
    "    print(\"函数内取值：\",mylist)\n",
    "    return\n",
    " \n",
    "# 调用changeme函数\n",
    "mylist = [10,20,30]\n",
    "changeme( mylist )\n",
    "print (\"函数外取值: \", mylist)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 四、参数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 必需参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_str( str ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print(str)\n",
    "   return\n",
    " \n",
    "# 调用 printme 函数，不加参数会报错\n",
    "print_str()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 关键字参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_str( str ):\n",
    "    \"打印任何传入的字符串\"\n",
    "    print(str)\n",
    "    return\n",
    " \n",
    "#调用printme函数\n",
    "print_str( str = \"朴实无华数据科学\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 以下实例中演示了函数参数的使用不需要使用指定顺序："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def printinfo( name, age ):\n",
    "   \"\"\"打印任何传入的字符串\"\"\"\n",
    "   print (\"名字: \", name)\n",
    "   print (\"年龄: \", age)\n",
    "   return\n",
    " \n",
    "#调用printinfo函数\n",
    "printinfo( age=22, name=\"Clancey\" )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 默认参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def printinfo( name, age = 18 ):\n",
    "   \"\"\"打印任何传入的字符串\"\"\"\n",
    "   print (\"名字: \", name)\n",
    "   print (\"年龄: \", age)\n",
    "   return\n",
    " \n",
    "#调用printinfo函数\n",
    "printinfo( age=22, name=\"Clancey\" )\n",
    "print (\"------------------------\")\n",
    "printinfo( name=\"Clancey\" )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 不定长参数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 语法（一个星号以元组形式导入）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def functionname([formal_args,] *var_args_tuple ):\n",
    "   \"\"\"函数_文档字符串\"\"\"\n",
    "   function_suite\n",
    "   return [expression]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def printinfo( arg1, *vartuple ):\n",
    "   \"\"\"打印任何传入的参数\"\"\"\n",
    "   print (\"输出: \")\n",
    "   print (arg1)\n",
    "   print (vartuple)\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo( 70, 60, 50 )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def printinfo( arg1, *vartuple ):\n",
    "   \"\"\"打印任何传入的参数\"\"\"\n",
    "   print (\"输出: \")\n",
    "   print (arg1)\n",
    "   for var in vartuple:\n",
    "      print (var)\n",
    "   return\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo( 10 )\n",
    "printinfo( 70, 60, 50 )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 语法（两个星号以字典形式导入）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def functionname([formal_args,] **var_args_dict ):\n",
    "   \"\"\"函数_文档字符串\"\"\"\n",
    "   function_suite\n",
    "   return [expression]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def printinfo( arg1, **vardict ):\n",
    "   \"打印任何传入的参数\"\n",
    "   print (\"输出: \")\n",
    "   print (arg1)\n",
    "   print (vardict)\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo(1, a=2,b=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 单独出现星号 * 后的参数必须用关键字传入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(a,b,*,c):\n",
    "    return a+b+c\n",
    "f(1,2,3)\n",
    "f(1,2,c=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 五、匿名函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python 使用 lambda 来创建匿名函数。\n",
    "所谓匿名，意即不再使用 def 语句这样标准的形式定义一个函数。\n",
    "   lambda 只是一个表达式，函数体比 def 简单很多。\n",
    "   lambda的主体是一个表达式，而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。\n",
    "   lambda 函数拥有自己的命名空间，且不能访问自己参数列表之外或全局命名空间里的参数。\n",
    "   虽然lambda函数看起来只能写一行，却不等同于C或C++的内联函数，后者的目的是调用小函数时不占用栈内存从而增加运行效率。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 语法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lambda [arg1 [,arg2,.....argn]]:expression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum = lambda arg1, arg2: arg1 + arg2\n",
    " \n",
    "# 调用sum函数\n",
    "print (\"相加后的值为 : \", sum( 10, 20 ))\n",
    "print (\"相加后的值为 : \", sum( 20, 20 ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 六、return语句"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "return [表达式] 语句用于退出函数，选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值，以下实例演示了 return 语句的用法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sum( arg1, arg2 ):\n",
    "   # 返回2个参数的和.\"\n",
    "   total = arg1 + arg2\n",
    "   print (\"函数内 : \", total)\n",
    "   return total\n",
    " \n",
    "# 调用sum函数\n",
    "total = sum( 10, 20 )\n",
    "print (\"函数外 : \", total)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
